package com.auxgroup.smarthome;


import com.auxgroup.smarthome.utils.ProtocolConvertUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;

import java.util.Iterator;
import java.util.Map;

/**
 * Created by kevinchen on 2017/9/5.
 *  把数据点的值 转成 字节数组的工具
 *  主要用于saas平台的远程控制指令
 *  睡眠曲线控制 （只限于家用空调）
 *  协议详见A13表
 */
public class SleepDiyDatapointConvertUtils {

    private static int BC2 = 0x00;

    private static final String SRC = "31";

    private static final int SRC1 = 0x31;

    private static final String DST = "01";

    private static final int DST1 = 0x01;

    /**
     *  controlDatapointValuesMap的长度 /2  即为节点的长度
     * @param size
     * @return
     */
    private static String[] getCommonArr(int size){
        String bc = ProtocolConvertUtils.converDecimalto4HexStr(size/2 + 3);
        return new String[]{CommonControlFunction.HEAD,CommonControlFunction.CMD,
                CommonControlFunction.RET_CMD,bc};
    }


    private static int[] getCommonIntArr(int size){
        int bc1 = size/2 + 3;
        return new int[]{CommonControlFunction.APP2_DEV_NUM,CommonControlFunction.HEAD1,
                CommonControlFunction.HEAD2,CommonControlFunction.CMD1,CommonControlFunction.CMD2,
                CommonControlFunction.RET_CMD1,CommonControlFunction.RET_CMD2, bc1 ,BC2};
    }

    /**
     * 用于普通控制数据点的原始raw
     * @param controlDatapointValuesMap  key: 数据点名称 value:改变的具体值 这个映射一定要是有序的。(该映射的长度最短12，最长144，同时必须被12整除)
     * @return
     */
    public static Pair<String[],int[]> sleepDiydataPointConvertRawHexData(Map<String,String> controlDatapointValuesMap){
        int size = controlDatapointValuesMap.size();
        if (controlDatapointValuesMap == null || size < 12 || size > 144 || size % 12 != 0){
            throw new IllegalArgumentException("传入的普通控制的控制参数不合法！");
        }
        int nodeNum = size/2;
        String[] hexStrArr = new String[nodeNum+3];
        int[] hexNumArr = new int[nodeNum+3];
        hexStrArr[0] = SRC;
        hexNumArr[0] = SRC1;
        hexStrArr[1] = DST;
        hexNumArr[1] = DST1;
        //节点数的二位16进制
        String nodeNum2HexStr = ProtocolConvertUtils.converDecimalto2HexStr(nodeNum);
        hexStrArr[2] = nodeNum2HexStr;
        hexNumArr[2] = nodeNum; //节点数
        int count = 3;
        int i = 0 ;
        StringBuffer sb = new StringBuffer();
        for(Iterator<Map.Entry<String, String>> iterator = controlDatapointValuesMap.entrySet().iterator();
            iterator.hasNext();){
            Map.Entry<String, String> next = iterator.next();
            String name = next.getKey();
            SleepDiyDatapointControlEnum sleepDiyDatapointControlEnum = SleepDiyDatapointControlEnum.getSleepDiyDatapointControlEnum(name);
            String controlValueStr = controlDatapointValuesMap.get(name);
            if (StringUtils.isBlank(controlValueStr)){
                    throw new IllegalArgumentException(name+" control value is not empty.");
            }
            int min = sleepDiyDatapointControlEnum.getMin();
            int max = sleepDiyDatapointControlEnum.getMax();
            Integer controlValue = Integer.parseInt(controlValueStr);
            if( controlValue < min || controlValue > max){
                throw new IllegalArgumentException(name + " control value should be between " + min
                            + " and " + max+".");
            }
            int bitCount = sleepDiyDatapointControlEnum.getBitCount();
            String binaryStr = ProtocolConvertUtils.toBinaryString(controlValue, min, bitCount);
            sb.append(binaryStr);
            i++;
            if (i%2==0){
                String hexStr = ProtocolConvertUtils.converBinaryto2HexStr(sb.toString());
                sb = new StringBuffer();
                hexStrArr[count] = hexStr;
                int hexNum = ProtocolConvertUtils.convert2HexStrToDecimal(hexStr);
                hexNumArr[count] = hexNum;
                count++;
            }
        }
        return Pair.of(hexStrArr,hexNumArr);
    }


    /**
     * 获取FCC 16进制 字符串
     * FCC = HEAD + CMD + RETCMD + BC + DATA (16进制拼接而成的字符串)
     * @param dataStr
     * @param size
     * @return
     */
    private static String[] getCheckFccHexStrArr(String[] dataStr,int size){
        if (dataStr==null || dataStr.length <= 0){
            throw new IllegalArgumentException();
        }
        String[] data4HexStrArr = ProtocolConvertUtils.constructData4HexStrArr(dataStr);
        return ArrayUtils.addAll(getCommonArr(size), data4HexStrArr);
    }


    /**
     *   睡眠曲线控制 最终指令
     * @param controlDatapointValuesMap
     * @return
     */
    public static int[] getA13ControlRaw(Map<String,String> controlDatapointValuesMap){
        Pair<String[], int[]> dataPointConvertBytes = sleepDiydataPointConvertRawHexData(controlDatapointValuesMap);
        int size = controlDatapointValuesMap.size();
        String[] leftDataHexArr = dataPointConvertBytes.getLeft();
        String[] fccHexStrArr = getCheckFccHexStrArr(leftDataHexArr,size);
        String fcc = CommonControlFunction.getFCC(fccHexStrArr);
        int[] fccNumArr = ProtocolConvertUtils.getFccNumArr(fcc);
        int[] rightArr = dataPointConvertBytes.getRight();
        int[] addArr = ArrayUtils.addAll(getCommonIntArr(size), rightArr);
        return ArrayUtils.addAll(addArr,fccNumArr);
    }




}
